package objectIO;

import java.io.*;

/**
 * @Author Zhang Chao
 * @Date 2021/5/25 15:08
 * @Version 1.0
 */
public class TestDriver01 {
    public static void main(String[] args) {
        /*
        对象流：要求被对象流写出的类必须实现 Serializable 接口，表示这个对象可以被对象流通过序列化的方式进行 IO/网络传输操作；
             序列化：在IO、网络、不同存储介质之间进行对象信息传输的时候，所采用的一种方式；序列化主要是在跨介质的传输中保证数据对象的有序性；
             传输之前需要进行序列化处理，按照有序的顺序进行分块传输；在接收方，通过有序的编号进行复原的过程叫做反序列化；
             transient关键字：将被修饰的属性排除序列化的机制；被其修饰的属性，在序列化时该属性的值不会被进行保存，在反序列化时该属性值会赋默认值；

         // 扩展：
         深克隆和浅克隆；[深复制和浅复制]
            浅克隆： 给一个对象起另外一个名字；两个变量名同时执行同一个对象内存，叫做浅克隆；
            深克隆： 对一个已有的对象，在内存中新开辟一块空间，将已有对象的内容对应复制过来，这样在内存中有两个一摸一样的对象叫做深克隆。（克隆羊多莉）
                    一般使用对象流来实现对象的深克隆复制；
                    因为： 基本类型在克隆的时候都是深克隆，但是引用类型，在克隆的时候一般默认都是浅克隆，所以深克隆需要手动来实现。
         */

        // 对象输出流
        writeObject();

        //////////////////////////////////////////
        // 从对象文件中读取一个对象到内存中
        Object object = readObject();
        System.out.println("反序列化之后的内容：" + object);

        // 再次读取一个对象到内存中
        Object object1 = readObject();

        // 请确认： object 和 object1 是不是同一个对象？
        System.out.println("object == object1:" + (object == object1));  //不是同一个了

    }

    /**
     * 使用对象流读取一个对象文件到内存中
     *
     * @return 读取到内存的对象
     */
    private static Object readObject() {
        // 返回的读取的对象
        Object object = null;
        // 使用对象输入流，将文件中的colaEmployee对象的信息以字节流的形式读取到内存中，其会复原为一个内存中的对象
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("F:\\Project-space\\java_demo\\java_basics_demo\\src\\objectIO\\emp_data.dat"));
            // 把文件中的对象写到内存中中
            object = objectInputStream.readObject();
            // 提示信息
            System.out.println("ColaEmployee已经读取到内存中");
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        //返回值
        return object;
    }

    /**
     * 将内存中的对象使用对象流写出到对象文件中
     */
    private static void writeObject() {
        //创建一个对象
        ColaEmployee colaEmployee = new ColaEmployee("安东尼", 4, 5);
        // 使用对象输出流，将内存中的colaEmployee对象的信息以字节流的形式写出到指定文件中
        try {
            // 声明创建一个对象输入流
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("F:\\Project-space\\java_demo\\java_basics_demo\\src\\objectIO\\emp_data.dat"));
            // 把内存中的对象写出到文件中
            objectOutputStream.writeObject(colaEmployee);
            // 提示信息
            System.out.println("ColaEmployee已经写出到对象文件中");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
